package cn.legym.garp.gateway.traffic.dynamic;

import com.alibaba.cloud.sentinel.SentinelProperties;
import com.alibaba.cloud.sentinel.datasource.RuleType;
import com.alibaba.csp.sentinel.property.SentinelProperty;
import org.springframework.context.ApplicationContext;

import java.util.Set;

/**
 * create by pipisun on 2021/9/13
 * copyright © 2017-2021 Legym Technology Co.,Ltd. All rights reserve
 * d.
 * file description:
 *
 * 为 动态资源管理器{@link DynamicResourceManager} 提供的 Sentinel规则监听器。
 *
 * 自定义动态规则定义{@link cn.legym.garp.gateway.traffic.dynamic.bean.DynamicResourceDefinition}
 * 生成的动态资源在本地维护，当Sentinel规则数据发生变更后，本地的动态资源/规则需要有相应策略同步到Sentinel资源集合内。
 * <p>
 * last update by {} on {}
 * update description:
 *
 * @see com.alibaba.cloud.sentinel.datasource.config.DataSourcePropertiesConfiguration
 */
public interface SentinelDatasourceWatcher {

    /**
     * Sentinel规则加载完成后，初始化监视器。
     *
     * 持有{@link SentinelProperty}引用并对其增加自定义的{@link InternalSentinelListener}
     * 以实现数据变更监视。
     *
     * @param context spring bean context
     * @param sentinelProperties sentinel数据源
     */
    void onInit(ApplicationContext context, SentinelProperties sentinelProperties);

    SentinelDatasourceWatcher addListener(InternalSentinelListener listener);

    SentinelDatasourceWatcher removeListener(InternalSentinelListener listener);

    Set<InternalSentinelListener> getListeners();

    SentinelProperty<?> getSourceByType(RuleType ruleType);

    interface InternalSentinelListener {
        /**
         * Sentinel规则发生变更的通知。
         *
         * 需要在此方法中，将本地维护的动态资源动态规则整合到本地Sentinel资源集合内。
         * @param ruleType 变化规则类型
         * @param value 数据
         */
        void onChange(RuleType ruleType, Object value);
    }
}
